/**
@file
	LogDevice.h
@brief

@author
	GengYong
@revision
	2005/11/05 * Created by GengYong.
*/


#ifndef SAF_HEADER_FILE_LOGDEVICE_H
#define SAF_HEADER_FILE_LOGDEVICE_H

#include <cstdarg>

namespace PrivateUtil
{
	enum
	{
		OUTLEVEL_DEBUG,
		OUTLEVEL_LOG,
		OUTLEVEL_WARN,
		OUTLEVEL_ERROR
	};

	class LogDevice
	{
	private:
		LogDevice(){;}
		virtual ~LogDevice(){;}
	public:
		static const LogDevice& Instance()
		{
			static LogDevice logdev;
			return logdev;
		}
	public:		
		virtual void Output(int level, const char * fmt, va_list args) const;
		virtual void Outputln(int level, const char * fmt, va_list args) const;
		virtual void OutputRaw(int level, const char * fmt, ...) const
#if defined(__GNUC__)
			__attribute__ ((format (printf, 3, 4)))
#endif
			;
	};
	
	typedef void (* BODYOUTER)(const char * fmt, ...)
#if defined(__GNUC__)
			__attribute__ ((format (printf, 1, 2)))
#endif
		;

	template<int OUTLEVEL>
	void _internal_body_outer_(const char * fmt, ...)
	{
		va_list args;
		va_start(args, fmt);
		LogDevice::Instance().Outputln(OUTLEVEL, fmt, args);
		va_end(args);
		return;
	}

	template<int OUTLEVEL>
	BODYOUTER _internal_header_outer_(const char * file, int line)
	{
		LogDevice::Instance().OutputRaw(OUTLEVEL, "line %d in %s:\n    ", line, file);
		return _internal_body_outer_<OUTLEVEL>;
	}

	template<int OUTLEVEL>
	BODYOUTER _internal_header_outer_()
	{		
		return _internal_body_outer_<OUTLEVEL>;
	}
}

#ifndef	DISABLE_LOGDEVICE
#	if defined(_DEBUG)
#		define SAFDBG	PrivateUtil::_internal_header_outer_<PrivateUtil::OUTLEVEL_DEBUG>(/*__FILE__, __LINE__*/)
#		define SAFLOG	PrivateUtil::_internal_header_outer_<PrivateUtil::OUTLEVEL_LOG>(/*__FILE__, __LINE__*/)
#		define SAFWAR	PrivateUtil::_internal_header_outer_<PrivateUtil::OUTLEVEL_WARN>(/*__FILE__, __LINE__*/)
#		define SAFERR	PrivateUtil::_internal_header_outer_<PrivateUtil::OUTLEVEL_ERROR>(/*__FILE__, __LINE__*/)
#	else
#		define SAFDBG
#		define SAFLOG	PrivateUtil::_internal_header_outer_<PrivateUtil::OUTLEVEL_LOG>()
#		define SAFWAR	PrivateUtil::_internal_header_outer_<PrivateUtil::OUTLEVEL_WARN>()
#		define SAFERR	PrivateUtil::_internal_header_outer_<PrivateUtil::OUTLEVEL_ERROR>()
#	endif
#else
#	define SAFDBG
#	define SAFLOG
#	define SAFWAR
#	define SAFERR
#endif	//#ifndef	DISABLE_LOGDEVICE


#endif	//#ifndef SAF_HEADER_FILE_LOGDEVICE_H
